home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 April: Mac OS SDK / Dev.CD Apr 97 SDK1.toast / Development Kits (Disc 1) / QuickDraw 3D / Samples / SampleCode / QD3D Pascal Demos / START HERE - Box / Box3DSupport.p < prev    next >
Encoding:
Text File  |  1996-11-15  |  14.7 KB  |  508 lines  |  [TEXT/CWIE]

  1. {This file was processed by Dan's Source Converter}
  2. {version 1.3 (this version modified by Ingemar Ragnemalm)}
  3.  
  4.  
  5. {09-15-96 Should be working now}
  6. {Matt Mora fixed some porting bugs}
  7. {mxmora@apple.com}
  8.  
  9.  
  10. unit Box3DSupport;
  11. interface
  12.     uses
  13.         Types, QuickDraw, Events, Windows, Dialogs, Fonts, DiskInit, TextEdit, Traps,{}
  14.         Memory, SegLoad, Scrap, ToolUtils, OSUtils, Menus, Resources, StandardFile,{}
  15.         GestaltEqu, Files, Errors, Devices, QuickDrawText, TextUtils, {}
  16.         QDOffScreen, 
  17.  
  18.         QD3D, QD3DDrawContext, QD3DRenderer, QD3DShader, QD3DCamera, QD3DLight, QD3DGeometry, QD3DGroup, QD3DMath, QD3DSet, QD3DTransform, QD3DAcceleration, QD3DView;
  19.  
  20.  
  21.     function MyQD3DInitialize (): OSErr;
  22.     function MyQD3DExit: OSErr;
  23.  
  24.     function MyNewView (theWindow: WindowPtr): TQ3ViewObject;
  25.     function MyNewDrawContext (theWindow: WindowPtr): TQ3DrawContextObject;
  26.     function MyNewCamera (theWindow: WindowPtr): TQ3CameraObject;
  27.     function MyNewLights (): TQ3GroupObject;
  28.     function MyNewModel (): TQ3GroupObject;
  29.  
  30.     function InputHelloWorldModel: TQ3GroupObject;
  31.     function InputFactModel: TQ3GroupObject;
  32.  
  33.     function AdjustCamera (theView: TQ3ViewObject; mainGroup: TQ3GroupObject; winWidth: Integer; winHeight: Integer): TQ3Point3D;
  34.  
  35. implementation
  36.  
  37. { My3dSupport.c - QuickDraw 3d routines}
  38. {}
  39. { This file contains utility routines for QuickDraw 3d sample code.}
  40. { This is a simple QuickDraw 3d application to draw a cube in the center }
  41. { of the main application window.  The routines in here handle setting up}
  42. { the main display group, the view, the Macintosh 3D draw context, and the}
  43. { camera and lighting. }
  44. {}
  45. { This code is the basis of the introductory article in  d e v e l o p  issue 22}
  46. {}
  47. { Nick Thompson - January 6th 1995}
  48. { }
  49. { ©1994-95 Apple computer Inc., All Rights Reserved}
  50.  
  51.  
  52.     var
  53.         documentGroupCenter: TQ3Point3D;
  54.         documentGroupScale: Real;
  55.  
  56.  
  57.     function MyNewView (theWindow: WindowPtr): TQ3ViewObject;
  58.  
  59.         var
  60.             myStatus: TQ3Status;
  61.             myView: TQ3ViewObject;
  62.             myDrawContext: TQ3DrawContextObject;
  63.             myRenderer: TQ3RendererObject;
  64.             myCamera: TQ3CameraObject;
  65.             myLights: TQ3GroupObject;
  66.             label bail;
  67.     begin
  68.         myView := Q3View_New;
  69.  
  70.     {    Create and set draw context.}
  71.         myDrawContext := MyNewDrawContext(theWindow);
  72.         if myDrawContext = nil then
  73.             goto bail;
  74.  
  75.         myStatus := Q3View_SetDrawContext(myView, myDrawContext);
  76.         if myStatus = kQ3Failure then
  77.             goto bail;
  78.  
  79.         myStatus := Q3Object_Dispose(myDrawContext);
  80.  
  81.     {    Create and set renderer.}
  82.  
  83.  
  84.  
  85.     { this would use the Z-Buffer renderer}
  86.         if false then
  87.             begin
  88.  
  89. (*    myRenderer := Q3Renderer_NewFromType(kQ3RendererTypeWireFrame);}
  90. {    If  ((myStatus := Q3View_SetRenderer(myView, myRenderer)) = kQ3Failure ) Then }
  91. {            goto bail;}
  92. {*)
  93.             end
  94.         else
  95.             begin
  96.     { this would use the interactive software renderer}
  97.  
  98.                 myRenderer := Q3Renderer_NewFromType(kQ3RendererTypeInteractive);
  99.                 if myRenderer <> nil then
  100.                     begin
  101.                         myStatus := Q3View_SetRenderer(myView, myRenderer);
  102.                         if myStatus = kQ3Failure then
  103.                             goto bail;
  104.         { these two lines set us up to use the best possible renderer,}
  105.         { including  hardware if it is installed.}
  106.                         myStatus := Q3InteractiveRenderer_SetDoubleBufferBypass(myRenderer, kQ3True);
  107.                         myStatus := Q3InteractiveRenderer_SetPreferences(myRenderer, kQAVendor_BestChoice, 0);
  108.  
  109.                     end
  110.                 else
  111.                     goto bail;
  112.             end;
  113.  
  114.         myStatus := Q3Object_Dispose(myRenderer);
  115.  
  116.         myCamera := MyNewCamera(theWindow);
  117.     {    Create and set camera.}
  118.         if (myCamera = nil) then
  119.             goto bail;
  120.  
  121.         myStatus := Q3View_SetCamera(myView, myCamera);
  122.         if myStatus = kQ3Failure then
  123.             goto bail;
  124.  
  125.         myStatus := Q3Object_Dispose(myCamera);
  126.  
  127.     {    Create and set lights.}
  128.         myLights := MyNewLights;
  129.         if myLights = nil then
  130.             goto bail;
  131.  
  132.         myStatus := Q3View_SetLightGroup(myView, myLights);
  133.         if myStatus = kQ3Failure then
  134.             goto bail;
  135.  
  136.         myStatus := Q3Object_Dispose(myLights);
  137.  
  138.     {    Done!!!}
  139.         MyNewView := myView;
  140.         exit(MyNewView); {mxm}
  141.         bail:
  142.     {    If any of the above failed, then don't return a view.}
  143.         MyNewView := nil;
  144.     end;
  145.  
  146. {----------------------------------------------------------------------------------}
  147.  
  148.     function MyNewDrawContext (theWindow: WindowPtr): TQ3DrawContextObject;
  149.  
  150.         var
  151.             myDrawContextData: TQ3DrawContextData;
  152.             myMacDrawContextData: TQ3MacDrawContextData;
  153.             ClearColor: TQ3ColorARGB;
  154.             myDrawContext: TQ3DrawContextObject;
  155.  
  156.     {    Set the background color.}
  157.     begin
  158.         ClearColor.a := 1.0;
  159.         ClearColor.r := 1.0;
  160.         ClearColor.g := 1.0;
  161.         ClearColor.b := 1.0;
  162.  
  163.     {    Fill in draw context data.}
  164.         myDrawContextData.clearImageMethod := kQ3ClearMethodWithColor;
  165.         myDrawContextData.clearImageColor := ClearColor;
  166.         myDrawContextData.paneState := kQ3False;
  167.         myDrawContextData.maskState := kQ3False;
  168.         myDrawContextData.doubleBufferState := kQ3True;
  169.  
  170.         myMacDrawContextData.drawContextData := myDrawContextData;
  171.  
  172.         myMacDrawContextData.window := CGrafPtr(theWindow);        { this is the window associated with the view}
  173.         myMacDrawContextData.library := kQ3Mac2DLibraryNone;
  174.         myMacDrawContextData.viewPort := nil;
  175.         myMacDrawContextData.grafPort := nil;
  176.  
  177.     {    Create draw context and return it, if it’s nil the caller must handle}
  178.         myDrawContext := Q3MacDrawContext_New(myMacDrawContextData);
  179.  
  180.         MyNewDrawContext := myDrawContext;
  181.     end;
  182.  
  183.  
  184. {----------------------------------------------------------------------------------}
  185.     function MakePoint3D (x, y, z: Real): TQ3Point3D;
  186. {----------------------------------------------------------------------------------}
  187.     begin
  188.         MakePoint3D.x := x;
  189.         MakePoint3D.y := y;
  190.         MakePoint3D.z := z;
  191.     end;
  192.  
  193. {----------------------------------------------------------------------------------}
  194.     function MakeVector3D (x, y, z: Real): TQ3Vector3D;
  195. {----------------------------------------------------------------------------------}
  196.     begin
  197.         MakeVector3D.x := x;
  198.         MakeVector3D.y := y;
  199.         MakeVector3D.z := z;
  200.     end;
  201.  
  202. {----------------------------------------------------------------------------------}
  203.     function MakeColorRGB (r, g, b: Real): TQ3ColorRGB;
  204. {----------------------------------------------------------------------------------}
  205.     begin
  206.         MakeColorRGB.r := r;
  207.         MakeColorRGB.g := g;
  208.         MakeColorRGB.b := b;
  209.     end;
  210.  
  211. {----------------------------------------------------------------------------------}
  212.     function MyNewCamera (theWindow: WindowPtr): TQ3CameraObject;
  213. {----------------------------------------------------------------------------------}
  214.  
  215.         var
  216.             perspectiveData: TQ3ViewAngleAspectCameraData;
  217.             camera: TQ3CameraObject;
  218.  
  219.             fieldOfView: Real;
  220.             hither: Real;
  221.             yon: Real;
  222.             returnVal: TQ3Status;
  223.  
  224.     begin
  225.         fieldOfView := 1.0;
  226.         hither := 0.001;
  227.         yon := 1000;
  228.         returnVal := kQ3Failure;
  229.  
  230.         perspectiveData.cameraData.placement.cameraLocation := MakePoint3D(0.0, 0.0, 7.0);    {from}
  231.         perspectiveData.cameraData.placement.pointOfInterest := MakePoint3D(0.0, 0.0, 0.0);    {to}
  232.         perspectiveData.cameraData.placement.upVector := MakeVector3D(0.0, 1.0, 0.0);    {up}
  233.  
  234.         perspectiveData.cameraData.range.hither := hither;
  235.         perspectiveData.cameraData.range.yon := yon;
  236.  
  237.         perspectiveData.cameraData.viewPort.origin.x := -1.0;
  238.         perspectiveData.cameraData.viewPort.origin.y := 1.0;
  239.         perspectiveData.cameraData.viewPort.width := 2.0;
  240.         perspectiveData.cameraData.viewPort.height := 2.0;
  241.  
  242.         perspectiveData.fov := fieldOfView;
  243.         perspectiveData.aspectRatioXToY := (theWindow^.portRect.right - theWindow^.portRect.left) / (theWindow^.portRect.bottom - theWindow^.portRect.top);
  244.  
  245.         camera := Q3ViewAngleAspectCamera_New(perspectiveData);
  246.  
  247.         MyNewCamera := camera;
  248.     end;
  249.  
  250.  
  251.  
  252. {----------------------------------------------------------------------------------}
  253.     function MyNewLights: TQ3GroupObject;
  254. {----------------------------------------------------------------------------------}
  255.  
  256.         var
  257.             myGroupPosition: TQ3GroupPosition;
  258.             myLightList: TQ3GroupObject;
  259.             myLightData: TQ3LightData;
  260.             myPointLightData: TQ3PointLightData;
  261.             myDirectionalLightData: TQ3DirectionalLightData;
  262.             myAmbientLight, myPointLight, myFillLight: TQ3LightObject;
  263.             pointLocation: TQ3Point3D;
  264.             fillDirection: TQ3Vector3D;
  265.             WhiteLight: TQ3ColorRGB;
  266.             myStatus: TQ3Status;
  267.  
  268.     {    Set up light data for ambient light.  This light data will be used for point and fill}
  269.     {    light also.}
  270.             label bail;
  271.     begin
  272.         pointLocation := MakePoint3D(-10.0, 0.0, 10.0);
  273.         fillDirection := MakeVector3D(10.0, 0.0, 10.0);
  274.         WhiteLight := MakeColorRGB(1.0, 1.0, 1.0);
  275.  
  276.  
  277.         myLightData.isOn := kQ3True;
  278.         myLightData.color := WhiteLight;
  279.  
  280.     {    Create ambient light.}
  281.         myLightData.brightness := 0.2;
  282.         myAmbientLight := Q3AmbientLight_New(myLightData);
  283.         if (myAmbientLight = nil) then
  284.             goto bail;
  285.  
  286.     {    Create point light.}
  287.         myLightData.brightness := 1.0;
  288.         myPointLightData.lightData := myLightData;
  289.         myPointLightData.castsShadows := kQ3False;
  290.         myPointLightData.attenuation := kQ3AttenuationTypeNone;
  291.         myPointLightData.location := pointLocation;
  292.         myPointLight := Q3PointLight_New(myPointLightData);
  293.         if (myPointLight = nil) then
  294.             goto bail;
  295.  
  296.     {    Create fill light.}
  297.         myLightData.brightness := 0.2;
  298.         myDirectionalLightData.lightData := myLightData;
  299.         myDirectionalLightData.castsShadows := kQ3False;
  300.         myDirectionalLightData.direction := fillDirection;
  301.         myFillLight := Q3DirectionalLight_New(myDirectionalLightData);
  302.         if (myFillLight = nil) then
  303.             goto bail;
  304.  
  305.     {    Create light group and add each of the lights into the group.}
  306.         myLightList := Q3LightGroup_New;
  307.         if (myLightList = nil) then
  308.             goto bail;
  309.         myGroupPosition := Q3Group_AddObject(myLightList, myAmbientLight);
  310.         if (myGroupPosition = nil) then
  311.             goto bail;
  312.         myGroupPosition := Q3Group_AddObject(myLightList, myPointLight);
  313.         if (myGroupPosition = nil) then
  314.             goto bail;
  315.         myGroupPosition := Q3Group_AddObject(myLightList, myFillLight);
  316.         if (myGroupPosition = nil) then
  317.             goto bail;
  318.  
  319.         myStatus := Q3Object_Dispose(myAmbientLight);
  320.         myStatus := Q3Object_Dispose(myPointLight);
  321.         myStatus := Q3Object_Dispose(myFillLight);
  322.  
  323.     {    Done!}
  324.         MyNewLights := myLightList;
  325.         exit(MyNewLights); {mxm}
  326.  
  327.         bail:
  328.     {    If any of the above failed, then return nothing!}
  329.         MyNewLights := nil;
  330.     end;
  331.  
  332. (*
  333.     { now longer needed since TQ3AttributeSetArrayPtr is now used in TQ3BoxData } 
  334.     type
  335.         PtrArr = packed array[0..0] of Ptr; {This *might* match the faceAttributeSet!}
  336.         PtrArrPtr = ^PtrArr;
  337. *)
  338.  
  339.  
  340. {----------------------------------------------------------------------------------}
  341.     procedure MyColorBoxFaces (var myBoxData: TQ3BoxData);
  342. {----------------------------------------------------------------------------------}
  343.  
  344.         var
  345.             faceColor: TQ3ColorRGB;
  346.             face: Integer;
  347.             myStatus: TQ3Status;
  348.  
  349.     { sanity check - you need to have set up }
  350.     { the face attribute set for the box data }
  351.     { before calling this.}
  352.  
  353.     begin
  354.         if (myBoxData.faceAttributeSet = nil) then
  355.             Exit(MyColorBoxFaces);
  356.  
  357.     { make each face of a box a different color}
  358.  
  359.         for face := 0 to 5 do
  360.             begin
  361.                 myBoxData.faceAttributeSet^[face] := Q3AttributeSet_New;
  362.                 case face of
  363.                     0: 
  364.                         begin
  365.                             faceColor.r := 1.0;
  366.                             faceColor.g := 0.0;
  367.                             faceColor.b := 0.0;
  368.                         end;
  369.                     1: 
  370.                         begin
  371.                             faceColor.r := 0.0;
  372.                             faceColor.g := 1.0;
  373.                             faceColor.b := 0.0;
  374.                         end;
  375.  
  376.                     2: 
  377.                         begin
  378.                             faceColor.r := 0.0;
  379.                             faceColor.g := 0.0;
  380.                             faceColor.b := 1.0;
  381.                         end;
  382.  
  383.                     3: 
  384.                         begin
  385.                             faceColor.r := 1.0;
  386.                             faceColor.g := 1.0;
  387.                             faceColor.b := 0.0;
  388.                         end;
  389.  
  390.                     4: 
  391.                         begin
  392.                             faceColor.r := 1.0;
  393.                             faceColor.g := 0.0;
  394.                             faceColor.b := 1.0;
  395.                         end;
  396.  
  397.                     5: 
  398.                         begin
  399.                             faceColor.r := 0.0;
  400.                             faceColor.g := 1.0;
  401.                             faceColor.b := 1.0;
  402.                         end;
  403.                 end;
  404.                 myStatus := Q3AttributeSet_Add(myBoxData.faceAttributeSet^[face], kQ3AttributeTypeDiffuseColor, @faceColor);
  405.             end;
  406.     end;
  407.  
  408. {----------------------------------------------------------------------------------}
  409.     function MyAddTransformedObjectToGroup (theGroup: TQ3GroupObject; theObject: TQ3Object; var translation: TQ3Vector3D): TQ3GroupPosition;
  410. {----------------------------------------------------------------------------------}
  411.  
  412.         var
  413.             transform: TQ3TransformObject;
  414.             myStatus: TQ3Status;
  415.             myGroupPosition: TQ3GroupPosition;
  416.     begin
  417.         transform := Q3TranslateTransform_New(translation);
  418.         myGroupPosition := Q3Group_AddObject(theGroup, transform);
  419.         myStatus := Q3Object_Dispose(transform);
  420.         MyAddTransformedObjectToGroup := Q3Group_AddObject(theGroup, theObject);
  421.     end;
  422.  
  423.  
  424. {----------------------------------------------------------------------------------}
  425.     function MyNewModel: TQ3GroupObject;
  426. {----------------------------------------------------------------------------------}
  427.         var
  428.             myGroup: TQ3GroupObject;
  429.             myBox: TQ3GeometryObject;
  430.             myBoxData: TQ3BoxData;
  431.             myGroupPosition: TQ3GroupPosition;
  432.             myIlluminationShader: TQ3ShaderObject;
  433.             translation: TQ3Vector3D;
  434.  
  435.             faces: array[0..5] of TQ3SetObject;
  436.             face: Integer;
  437.             myPoint3DPtr: TQ3Point3DPtr;
  438.             myVector3DPtr: TQ3Vector3DPtr;
  439.             myStatus: TQ3Status;
  440.  
  441.     { Create a group for the complete model.}
  442.     { do not use Q3OrderedDisplayGroup_New since in this}
  443.     { type of group all of the translations are applied before}
  444.     { the objects in the group are drawn, in this instance we }
  445.     { dont want this.}
  446.     begin
  447.         myGroup := Q3DisplayGroup_New;
  448.         if myGroup <> nil then
  449.  
  450.         { Define a shading type for the group}
  451.         { and add the shader to the group}
  452.             begin
  453.                 myIlluminationShader := Q3PhongIllumination_New;
  454.                 myGroupPosition := Q3Group_AddObject(myGroup, myIlluminationShader);
  455.  
  456.         { set up the colored faces for the box data}
  457.                 myBoxData.faceAttributeSet := @faces;
  458.                 myBoxData.boxAttributeSet := nil;
  459.                 MyColorBoxFaces(myBoxData);
  460.  
  461.         { create the box itself}
  462.                 myPoint3DPtr := Q3Point3D_Set(myBoxData.origin, 0, 0, 0);
  463.                 myVector3DPtr := Q3Vector3D_Set(myBoxData.orientation, 0, 1, 0);
  464.                 myVector3DPtr := Q3Vector3D_Set(myBoxData.majorAxis, 0, 0, 1);
  465.                 myVector3DPtr := Q3Vector3D_Set(myBoxData.minorAxis, 1, 0, 0);
  466.                 myBox := Q3Box_New(myBoxData);
  467.  
  468.         { put four copies of the box into the group, each one with its own translation}
  469.                 translation.x := 0;
  470.                 translation.y := 0;
  471.                 translation.z := 0;
  472.                 myGroupPosition := MyAddTransformedObjectToGroup(myGroup, myBox, translation);
  473.  
  474.                 translation.x := 2;
  475.                 translation.y := 0;
  476.                 translation.z := 0;
  477.                 myGroupPosition := MyAddTransformedObjectToGroup(myGroup, myBox, translation);
  478.  
  479.                 translation.x := 0;
  480.                 translation.y := 0;
  481.                 translation.z := -2;
  482.                 myGroupPosition := MyAddTransformedObjectToGroup(myGroup, myBox, translation);
  483.  
  484.                 translation.x := -2;
  485.                 translation.y := 0;
  486.                 translation.z := 0;
  487.                 myGroupPosition := MyAddTransformedObjectToGroup(myGroup, myBox, translation);
  488.             end;
  489.  
  490.     { dispose of the objects we created here}
  491.         if (myIlluminationShader <> nil) then
  492.             myStatus := Q3Object_Dispose(myIlluminationShader);
  493.  
  494.         for face := 0 to 5 do
  495.             begin
  496.                 if myBoxData.faceAttributeSet^[face] <> nil then
  497.                     myStatus := Q3Object_Dispose(myBoxData.faceAttributeSet^[face]);
  498.             end;
  499.  
  500.         if myBox <> nil then
  501.             myStatus := Q3Object_Dispose(myBox);
  502.  
  503.     {    Done!}
  504.         MyNewModel := myGroup;
  505.     end;
  506.  
  507. end.
  508.